package com.atguigu.gmall.cart.service.impl;

import com.atguigu.gmall.cart.service.CartService;
import com.atguigu.gmall.common.constant.RedisConst;
import com.atguigu.gmall.common.result.Result;
import com.atguigu.gmall.common.util.AuthContextHolder;
import com.atguigu.gmall.common.util.DateUtil;
import com.atguigu.gmall.model.cart.CartInfo;
import com.atguigu.gmall.model.product.SkuInfo;
import com.atguigu.gmall.product.client.ProductFeignClient;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.unit.DataUnit;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @version 1.0
 * @Author 杨旭康
 * @Date 2023/2/7 16:59
 * @question:
 */

@Service
public class CartServiceImpl implements CartService {

    @Autowired
    private ProductFeignClient productFeignClient;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 加入购物车
     * 1.添加购物车时 先去redis获取看看是否已经存在 若存在则更新时间与个数 若不存在则新建
     * 2.存储方式:  userId:skuId:cartInfo [key:field:value]
     *
     * @param skuId
     * @param skuNum
     * @param userId
     */
    @Override
    public void addToCart(Long skuId, Integer skuNum, String userId) {

        //获取操作购物车的key user:用户id:cart
        String cartKey = this.getKey(userId);
        //获取购物车列表 String == user:1:cart , String == 22 , CartInfo == 详情
        BoundHashOperations<String, String, CartInfo> boundHashOps = redisTemplate.boundHashOps(cartKey);
        //定义购车详情信息对象
        CartInfo cartInfo = null;

        //判断当前列表是否包含sku
        if (boundHashOps.hasKey(skuId.toString())) {
            //存在
            cartInfo = boundHashOps.get(skuId.toString());
            cartInfo.setSkuNum(cartInfo.getSkuNum() + skuNum);
            cartInfo.setUpdateTime(new Date());
            cartInfo.setSkuPrice(productFeignClient.getSkuPrice(skuId));
        } else {
            //不存在
            cartInfo = new CartInfo();
            cartInfo.setUserId(userId);
            cartInfo.setSkuId(skuId);
            //远程请求sku详情数据
            SkuInfo skuInfo = productFeignClient.getSkuInfo(skuId);

            cartInfo.setCartPrice(skuInfo.getPrice());
            cartInfo.setSkuNum(skuNum);
            cartInfo.setImgUrl(skuInfo.getSkuDefaultImg());
            cartInfo.setSkuName(skuInfo.getSkuName());
            cartInfo.setCreateTime(new Date());
            cartInfo.setUpdateTime(new Date());
            //实时价格
            cartInfo.setSkuPrice(skuInfo.getPrice());
        }
        //存储
        boundHashOps.put(skuId.toString(), cartInfo);
    }

    /**
     * 展示购物车--合并购物车
     * 1.先获取未登录的购物车 再查看是否登录 若登录开启合并
     * 2.登录后的购物车-合并
     *
     * @param userId
     * @param userTempId
     * @return
     */
    @Override
    public List<CartInfo> cartList(String userId, String userTempId) {

        //定义未登录购物车
        List<CartInfo> noLoginCartList = null;
        //获取未登录数据
        if (!StringUtils.isEmpty(userTempId)) {
            //获取的是list(一个个sku)集合 只传个userId即可
            noLoginCartList = redisTemplate.boundHashOps(this.getKey(userTempId)).values();
        }
        //表示未登录
        if (StringUtils.isEmpty(userId) && !CollectionUtils.isEmpty(noLoginCartList)) {
            noLoginCartList.sort((o1, o2) -> {
                return DateUtil.truncatedCompareTo(o2.getUpdateTime(), o1.getUpdateTime(), Calendar.SECOND);
            });
            return noLoginCartList;
        }

        //到了此处 代表已经登陆开始合并
        List<CartInfo> loginCartList = null;
        //获取登录后的数据
        BoundHashOperations<String, String, CartInfo> boundHashOps = redisTemplate.boundHashOps(this.getKey(userId));
        //判断是否为空
        if (!CollectionUtils.isEmpty(noLoginCartList)) {
            //合并
            noLoginCartList.forEach(cartInfo -> {
                //判断登录后的集合中是否包含
                if (boundHashOps.hasKey(cartInfo.getSkuId().toString())) {
                    //已经在登录的购物车列表中存在 --数量更改
                    CartInfo loginCartInfo = boundHashOps.get(cartInfo.getSkuId().toString());
                    //更新数量
                    loginCartInfo.setSkuNum(loginCartInfo.getSkuNum() + cartInfo.getSkuNum());
                    //更新时间
                    loginCartInfo.setUpdateTime(new Date());
                    //是否选中 默认是选中
                    if (cartInfo.getIsChecked().intValue() == 1) {
                        loginCartInfo.setIsChecked(1);
                    }
                    boundHashOps.put(cartInfo.getSkuId().toString(), loginCartInfo);
                } else {
                    //到此处证明 该商品第一次出现 设置userId和更新时间即可
                    cartInfo.setUserId(userId);
                    cartInfo.setUpdateTime(new Date());
                    boundHashOps.put(cartInfo.getSkuId().toString(), cartInfo);
                }
            });
            //未登录的购物车数据--清除
            redisTemplate.delete(getKey(userTempId));
        }
        //重新换取购物车列表并且进行一个排序
        loginCartList = boundHashOps.values();
        if (CollectionUtils.isEmpty(loginCartList)) {
            loginCartList = new ArrayList<>();
        }
        //排序
        if (!CollectionUtils.isEmpty(loginCartList)) {
            loginCartList.sort((o1, o2) -> {
                return DateUtil.truncatedCompareTo(o2.getUpdateTime(), o1.getUpdateTime(), Calendar.SECOND);
            });
        }
        return loginCartList;
    }

    /**
     * 商品状态的选中
     * 只更改缓存中的isChecked即可
     * @param userId
     * @param isChecked
     * @param skuId
     */
    @Override
    public void checkCart(String userId, Integer isChecked, Long skuId) {

        BoundHashOperations<String,String,CartInfo> boundHashOperations = redisTemplate.boundHashOps(this.getKey(userId));
        CartInfo cartInfo = boundHashOperations.get(skuId);
        if (cartInfo != null) {
            //更新状态并且放到redis重新保存
            cartInfo.setIsChecked(isChecked);
            boundHashOperations.put(skuId.toString(),cartInfo);
        }
    }

    /**
     * 删除购物车
     * @param skuId
     * @param userId
     */
    @Override
    public void deleteCart(Long skuId, String userId) {
        BoundHashOperations<String, String, CartInfo> boundHashOps = this.redisTemplate.boundHashOps(this.getKey(userId));
        //  判断购物车中是否有该商品
        if (boundHashOps.hasKey(skuId.toString())){
            boundHashOps.delete(skuId.toString());
        }
    }


    /**
     * 获取操作购物车的key user:用户id:cart
     *
     * @param userId
     * @return
     */
    private String getKey(String userId) {
        return RedisConst.USER_KEY_PREFIX + userId + RedisConst.USER_CART_KEY_SUFFIX;
    }

}